import XLSX from 'xlsx';
import { getToken} from '@/utils/auth'
import { Message } from 'element-ui';

function auto_width(ws, data) {
    /*set worksheet max width per col*/
    const colWidth = data.map(row => row.map(val => {
        /*if null/undefined*/
        if (val == null) {
            return {'wch': 10};
        }
        /*if chinese*/
        else if (val.toString().charCodeAt(0) > 255) {
            return {'wch': val.toString().length * 2};
        } else {
            return {'wch': val.toString().length};
        }
    }))
    /*start in the first row*/
    let result = colWidth[0];
    for (let i = 1; i < colWidth.length; i++) {
        for (let j = 0; j < colWidth[i].length; j++) {
            if (result[j]['wch'] < colWidth[i][j]['wch']) {
                result[j]['wch'] = colWidth[i][j]['wch'];
            }
        }
    }
    ws['!cols'] = result;
}

function json_to_array(key, jsonData) {
    return jsonData.map(v => key.map(j => {
        return v[j]
    }));
}

// fix data,return string
function fixdata(data) {
    let o = ''
    let l = 0
    const w = 10240
    for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
    o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
    return o
}

// get head from excel file,return array
function get_header_row(sheet) {
    const headers = []
    const range = XLSX.utils.decode_range(sheet['!ref'])
    let C
    const R = range.s.r /* start in the first row */
    for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
        var cell = sheet[XLSX.utils.encode_cell({c: C, r: R})] /* find the cell in the first row */
        var hdr = 'UNKNOWN ' + C // <-- replace with your desired default
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
        headers.push(hdr)
    }
    return headers
}

export const export_table_to_excel = (id, filename) => {
    const table = document.getElementById(id);
    const wb = XLSX.utils.table_to_book(table);
    XLSX.writeFile(wb, filename);
}

export const export_json_to_excel = ({data, key, title, filename, autoWidth}) => {
    const wb = XLSX.utils.book_new();
    data.unshift(title);
    const ws = XLSX.utils.json_to_sheet(data, {header: key, skipHeader: true});
    if (autoWidth) {
        const arr = json_to_array(key, data);
        auto_width(ws, arr);
    }
    XLSX.utils.book_append_sheet(wb, ws, filename);
    XLSX.writeFile(wb, filename + '.xlsx');
}

export const export_array_to_excel = ({key, data, title, filename, autoWidth}) => {
    const wb = XLSX.utils.book_new();
    const arr = json_to_array(key, data);
    arr.unshift(title);
    const ws = XLSX.utils.aoa_to_sheet(arr);
    if (autoWidth) {
        auto_width(ws, arr);
    }
    XLSX.utils.book_append_sheet(wb, ws, filename);
    XLSX.writeFile(wb, filename + '.xlsx');
}

export const read = (data, type) => {
    const workbook = XLSX.read(data, {type: type});
    // console.log(workbook.SheetNames[0]);
    const firstSheetName = workbook.SheetNames[0];
    const worksheet = workbook.Sheets[firstSheetName];
    // console.log(worksheet);
    const header = get_header_row(worksheet);
    // console.log(header);
    const results = XLSX.utils.sheet_to_json(worksheet);
    // console.log(results)
    return {header, results};
}
export async function fetchFile( url, data = {}, method = 'GET', defaultFileName = 'null.xls', isLoading = false, callBack) {
    const request = {
      body: JSON.stringify(data),
      method: method,
      headers: {
        Authorization:'Bearer '+getToken(),
        'Content-Type': 'application/json;charset=UTF-8',
        Accept: '*/*',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Credentials': 'true',
        credentials: 'include', // 强制加入凭据头
      },
    };
    if (method == 'GET') delete request.body;
    if (isLoading) {
       Message('正在处理,请稍后...');
    }
    await fetch(url, request)
      .then(r1 => {
        let header = r1.headers.get('Content-Type');
        let idx = header.indexOf('application/json;');
        if (r1.status === 204) {
          return r1.text();
        } else if (idx >= 0) {
          // 下载流
          return r1.json();
        }
        return r1;
      })
      .then(async r2 => {
        // 文件流
        if (r2 instanceof Response) {
          /** ===注意===
       *  此处 response.headers.get('Content-Disposition')
       *  1、如何获取后端传过来的名字，后端需要设置如下：
          重要： Access-Control-Expose-Headers : 'Content-Disposition'
          2、注意点后台Content-Disposition，需要配合 application/octet- stream

          解决乱码
          转换方式有很多：
          方式一：将中文文件名用ISO-8859-1进行重新编码，如headers.add("Content-disposition","attachment;filename="+new String("中国".getBytes("UTF-8"),"ISO-8859-1")+".txt");
          方式二：可以对中文文件名使用url编码，如headers.add("Content-disposition","attachment;filename="+URLEncoder.encode("中国","UTF-8")+".txt");
      */
          let filename = defaultFileName;
          // console.log('测试1111',filename);
          // console.log('heders1',r2);
          // console.log('heders2',r2.headers);
          // console.log('heders3',r2.headers.get('Content-Disposition'));
          // if (r2.headers.get('Content-Disposition')) {
          //   filename = r2.headers.get('Content-Disposition').split(';')[1] .split('=')[1];
          // }
          const blob = await r2.blob();
          const link = document.createElement('a');
          link.download = filename;
          link.style.display = 'none';
          link.href = URL.createObjectURL(blob);
          document.body.appendChild(link);
          link.click();
          URL.revokeObjectURL(link.href);
          document.body.removeChild(link);
          if (isLoading) {
            Message({
              message: '下载成功',
              type: 'success'
            });
            if (callBack) {
              callBack();
            }
          }
        } else {
          //json
          if (isLoading) {
            Message({
              message: '恭喜你，下载成功',
              type: 'success'
            });
          }
          if (r2.code == 0) {
            Message.error('响应数据非文件流~');
          } else {
            Message.error(r2.msg);
          }
        }
      })
      .catch(err => {
        Message.error(`错误${err}`);
      });
    }

export default {
    export_table_to_excel,
    export_array_to_excel,
    export_json_to_excel,
    read,
    fetchFile
}
